package org.groupg.project.configmanager.ui;


import org.groupg.project.configmanager.model.SshConfig;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.io.File;

/**
 * SSH配置对话框 - 用于添加和编辑SSH配置
 */
public class SshConfigDialog extends JDialog {
    private SshConfig config;
    private boolean saved = false;

    // 表单字段
    private JTextField nameField;
    private JTextField hostField;
    private JTextField portField;
    private JTextField usernameField;
    private JTextField passwordField;
    private JTextField privateKeyPathField;

    // 按钮
    private JButton saveButton;
    private JButton cancelButton;
    private JButton testButton;
    private JButton browseButton;
    private JButton generateCommandButton;

    /**
     * 构造函数
     * @param owner 父窗口
     * @param config SSH配置对象，如果为null则创建新配置
     */
    public SshConfigDialog(Frame owner, SshConfig config) {
        super(owner, config == null ? "添加SSH配置" : "编辑SSH配置", true);
        this.config = config != null ? config : new SshConfig();
        initializeUI();
        populateFields();
    }

    /**
     * 初始化用户界面
     */
    private void initializeUI() {
        setLayout(new BorderLayout(10, 10));
        setSize(500, 400);
        setLocationRelativeTo(getOwner());
        setResizable(true);

        // 创建主面板
        JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        // 表单面板
        JPanel formPanel = new JPanel(new GridLayout(6, 2, 5, 10));

        // 名称字段
        formPanel.add(new JLabel("名称*:"));
        nameField = new JTextField();
        formPanel.add(nameField);

        // 主机地址
        formPanel.add(new JLabel("主机*:"));
        hostField = new JTextField();
        formPanel.add(hostField);

        // 端口
        formPanel.add(new JLabel("端口:"));
        portField = new JTextField("22");
        formPanel.add(portField);

        // 用户名
        formPanel.add(new JLabel("用户名*:"));
        usernameField = new JTextField();
        formPanel.add(usernameField);

        // 密码
        formPanel.add(new JLabel("密码:"));
        passwordField = new JPasswordField();
        formPanel.add(passwordField);

        // 私钥路径
        formPanel.add(new JLabel("私钥路径:"));
        JPanel keyPanel = new JPanel(new BorderLayout(5, 0));
        privateKeyPathField = new JTextField();
        browseButton = new JButton("浏览");
        browseButton.setMargin(new Insets(2, 5, 2, 5));
        keyPanel.add(privateKeyPathField, BorderLayout.CENTER);
        keyPanel.add(browseButton, BorderLayout.EAST);
        formPanel.add(keyPanel);

        // 添加表单面板到主面板
        mainPanel.add(formPanel, BorderLayout.CENTER);

        // 命令生成面板
        JPanel commandPanel = new JPanel(new BorderLayout(5, 5));
        commandPanel.setBorder(BorderFactory.createTitledBorder("SSH命令预览"));
        JTextArea commandArea = new JTextArea(3, 30);
        commandArea.setEditable(false);
        commandArea.setLineWrap(true);
        commandArea.setWrapStyleWord(true);
        commandArea.setBackground(UIManager.getColor("Panel.background"));
        JScrollPane commandScrollPane = new JScrollPane(commandArea);

        generateCommandButton = new JButton("生成命令");
        generateCommandButton.setMargin(new Insets(2, 5, 2, 5));

        commandPanel.add(commandScrollPane, BorderLayout.CENTER);
        commandPanel.add(generateCommandButton, BorderLayout.SOUTH);

        mainPanel.add(commandPanel, BorderLayout.SOUTH);

        // 按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        testButton = new JButton("测试连接");
        saveButton = new JButton("保存");
        cancelButton = new JButton("取消");

        // 设置按钮快捷键
        saveButton.setMnemonic('S');
        cancelButton.setMnemonic('C');
        testButton.setMnemonic('T');

        buttonPanel.add(testButton);
        buttonPanel.add(Box.createHorizontalStrut(10));
        buttonPanel.add(saveButton);
        buttonPanel.add(cancelButton);

        add(mainPanel, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);

        // 添加事件监听器
        setupEventListeners(commandArea);

        // 设置默认按钮
        getRootPane().setDefaultButton(saveButton);
    }

    /**
     * 设置事件监听器
     */
    private void setupEventListeners(JTextArea commandArea) {
        saveButton.addActionListener(e -> saveConfig());
        cancelButton.addActionListener(e -> dispose());
        testButton.addActionListener(e -> testConnection());
        browseButton.addActionListener(e -> browsePrivateKey());
        generateCommandButton.addActionListener(e -> generateAndDisplayCommand(commandArea));

        // 添加字段变化监听器，实时更新命令预览
        ActionListener updateCommandListener = e -> generateAndDisplayCommand(commandArea);
        hostField.addActionListener(updateCommandListener);
        portField.addActionListener(updateCommandListener);
        usernameField.addActionListener(updateCommandListener);
        privateKeyPathField.addActionListener(updateCommandListener);

        // 初始生成命令
        generateAndDisplayCommand(commandArea);
    }

    /**
     * 浏览私钥文件
     */
    private void browsePrivateKey() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        fileChooser.setDialogTitle("选择SSH私钥文件");

        // 设置文件过滤器（可选）
        fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
            @Override
            public boolean accept(File f) {
                return f.isDirectory() ||
                       f.getName().toLowerCase().endsWith(".pem") ||
                       f.getName().toLowerCase().endsWith(".key") ||
                       !f.getName().contains("."); // 无扩展名的私钥文件
            }

            @Override
            public String getDescription() {
                return "SSH私钥文件 (*.pem, *.key)";
            }
        });

        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            privateKeyPathField.setText(fileChooser.getSelectedFile().getAbsolutePath());
        }
    }

    /**
     * 生成并显示SSH命令
     */
    private void generateAndDisplayCommand(JTextArea commandArea) {
        SshConfig tempConfig = new SshConfig();
        tempConfig.setHost(hostField.getText());

        try {
            tempConfig.setPort(Integer.parseInt(portField.getText()));
        } catch (NumberFormatException e) {
            tempConfig.setPort(22); // 默认端口
        }

        tempConfig.setUsername(usernameField.getText());
        tempConfig.setPrivateKeyPath(privateKeyPathField.getText());

        String command = tempConfig.generateSshCommand();
        commandArea.setText(command);
    }

    /**
     * 用配置数据填充表单字段
     */
    private void populateFields() {
        if (config.getId() != null) {
            nameField.setText(config.getName() != null ? config.getName() : "");
            hostField.setText(config.getHost() != null ? config.getHost() : "");

            if (config.getPort() != null) {
                portField.setText(config.getPort().toString());
            } else {
                portField.setText("22");
            }

            usernameField.setText(config.getUsername() != null ? config.getUsername() : "");
            passwordField.setText(config.getPassword() != null ? config.getPassword() : "");
            privateKeyPathField.setText(config.getPrivateKeyPath() != null ? config.getPrivateKeyPath() : "");
        }
    }

    /**
     * 保存配置
     */
    private void saveConfig() {
        // 验证必填字段
        if (nameField.getText().trim().isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入配置名称", "错误", JOptionPane.ERROR_MESSAGE);
            nameField.requestFocus();
            return;
        }

        if (hostField.getText().trim().isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入主机地址", "错误", JOptionPane.ERROR_MESSAGE);
            hostField.requestFocus();
            return;
        }

        if (usernameField.getText().trim().isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入用户名", "错误", JOptionPane.ERROR_MESSAGE);
            usernameField.requestFocus();
            return;
        }

        // 验证端口号
        int port = 22; // 默认端口
        try {
            port = Integer.parseInt(portField.getText().trim());
            if (port < 1 || port > 65535) {
                JOptionPane.showMessageDialog(this, "端口号必须在1-65535范围内", "错误", JOptionPane.ERROR_MESSAGE);
                portField.requestFocus();
                return;
            }
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(this, "端口号必须是有效的数字", "错误", JOptionPane.ERROR_MESSAGE);
            portField.requestFocus();
            return;
        }

        // 验证私钥文件是否存在（如果提供了路径）
        String privateKeyPath = privateKeyPathField.getText().trim();
        if (!privateKeyPath.isEmpty()) {
            File keyFile = new File(privateKeyPath);
            if (!keyFile.exists()) {
                int result = JOptionPane.showConfirmDialog(this,
                    "指定的私钥文件不存在，是否继续保存？",
                    "文件不存在",
                    JOptionPane.YES_NO_OPTION);
                if (result != JOptionPane.YES_OPTION) {
                    privateKeyPathField.requestFocus();
                    return;
                }
            }
        }

        // 更新配置对象
        config.setName(nameField.getText().trim());
        config.setHost(hostField.getText().trim());
        config.setPort(port);
        config.setUsername(usernameField.getText().trim());
        config.setPassword(new String(passwordField.getText().trim()));
        config.setPrivateKeyPath(privateKeyPath);

        // 标记为已保存并关闭对话框
        saved = true;
        dispose();
    }

    /**
     * 测试SSH连接
     */
    private void testConnection() {
        // 基本验证
        if (hostField.getText().trim().isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入主机地址", "错误", JOptionPane.ERROR_MESSAGE);
            hostField.requestFocus();
            return;
        }

        if (usernameField.getText().trim().isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入用户名", "错误", JOptionPane.ERROR_MESSAGE);
            usernameField.requestFocus();
            return;
        }

        // 创建临时配置用于测试
        SshConfig testConfig = new SshConfig();
        testConfig.setHost(hostField.getText().trim());

        try {
            testConfig.setPort(Integer.parseInt(portField.getText().trim()));
        } catch (NumberFormatException e) {
            testConfig.setPort(22);
        }

        testConfig.setUsername(usernameField.getText().trim());
        testConfig.setPrivateKeyPath(privateKeyPathField.getText().trim());

        // 显示连接信息
        String testInfo = String.format(
            "SSH连接测试信息:\n\n" +
            "主机: %s\n" +
            "端口: %d\n" +
            "用户名: %s\n" +
            "认证方式: %s\n\n" +
            "注意: 实际连接测试使用ping命令验证主机可达性",
            testConfig.getHost(),
            testConfig.getPort(),
            testConfig.getUsername(),
            (testConfig.getPrivateKeyPath() != null && !testConfig.getPrivateKeyPath().isEmpty()) ?
            "私钥认证" : (!passwordField.getText().trim().isEmpty() ? "密码认证" : "无认证")
        );

        JOptionPane.showMessageDialog(this, testInfo, "SSH连接测试", JOptionPane.INFORMATION_MESSAGE);

        // 实际执行连接测试（可选）
        // boolean isReachable = SshConnectionService.testSshConnection(testConfig);
        // if (isReachable) {
        //     JOptionPane.showMessageDialog(this, "主机可达，可以连接", "测试成功", JOptionPane.INFORMATION_MESSAGE);
        // } else {
        //     JOptionPane.showMessageDialog(this, "无法连接到主机", "测试失败", JOptionPane.WARNING_MESSAGE);
        // }
    }

    /**
     * 检查配置是否已保存
     * @return 如果已保存返回true，否则返回false
     */
    public boolean isSaved() {
        return saved;
    }

    /**
     * 获取配置对象
     * @return 配置对象
     */
    public SshConfig getConfig() {
        return config;
    }
}